//
//  ViewerBase.m
//

#import "ViewerBase.h"

#import "Controller.h"
#import "FolderModel.h"
#import "FullScreenWindow.h"
#import "ImageView.h"
#import "PreferencesData.h"
#import "ThumbData.h"

#import "QTKit/QTKit.h"

@implementation ViewerBase

//--------------------------------------------------------------------------------------------------
- (void) awakeFromNib
{
	showIndex = NO;
	showImageSize = NO;
	showFileLength = NO;
	showDate = NO;
	showName = NO;
	fitWindow = YES;
	movieNaturalSize = YES;
	fullScreen = NO;

	[[imageView window] setDelegate: self];
	[imageView setDelegate: self];

	originalColor = [[imageView window] backgroundColor];
	[originalColor retain];


	movieNaturalSize = [[[Controller sharedController] preferencesData] useMovieNaturalSize];
	pathElements = [[[Controller sharedController] preferencesData] pathElements];
//	getBoolFromPreferences(userPrefs, PREF_FIT_WINDOW, &fitWindow);

	[[NSNotificationCenter defaultCenter] 
		addObserver: self
		selector: @selector (prefsDataChanged:)
		name: PBPrefencesDidChangeNotification
		object: nil];

	[[NSNotificationCenter defaultCenter] addObserver
		: self
		selector: @selector (movieSuperViewFrameChanged:)
		name: NSViewFrameDidChangeNotification
		object: [movieView superview]];
}

//------------------------------------------------------------------------------
- (void) dealloc
{
	[[NSNotificationCenter defaultCenter] removeObserver: self];

	[originalColor release];
	[[imageView window] setDelegate: nil];
	[[imageView window] close];

	[super dealloc];
}

//------------------------------------------------------------------------------
- (NSWindow*) mainWindow
{
	return [imageView window];
}

//------------------------------------------------------------------------------
- (void) prefsDataChanged:(NSNotification*) note
{
	[imageView setNeedsDisplay];

	if (movieNaturalSize != [[[Controller sharedController] preferencesData] useMovieNaturalSize])
	{
		movieNaturalSize = [[[Controller sharedController] preferencesData] useMovieNaturalSize];
		[self calcAndSetMovieFrame];
	}

	[[[imageView window] contentView] setNeedsDisplay: YES];
}

//------------------------------------------------------------------------------
// Keystrokes our image view forwards to us
- (void) imageView:(ImageView*) imgView  keyDown:(NSEvent *) evt
{
NSLog(@"ViewerBase.keyDown...");
}

//------------------------------------------------------------------------------
// Methods expected to be overridden in subclasses
//------------------------------------------------------------------------------
- (void) redrawCurrent
{
}

//------------------------------------------------------------------------------
- (void) movieDisplayed:(QTMovie*) movie
{
}

//------------------------------------------------------------------------------
- (BOOL) hasDirectory
{
	return NO;
}

//------------------------------------------------------------------------------
- (BOOL) hasSelectedJPEG
{
	return NO;
}

//------------------------------------------------------------------------------
- (BOOL) hasSelectedImage
{
NSLog(@"ViewerBase.hasSelectedImage");
	return NO;
}

//------------------------------------------------------------------------------
- (NSString*) currentFile
{
	return @"";
}

//------------------------------------------------------------------------------
- (NSString*) currentFolder
{
	return @"";
}

//------------------------------------------------------------------------------
- (int) sortBy;
{
	return SORT_BY_DATE;
}

//------------------------------------------------------------------------------
- (void) endFullScreenDuringClose
{
	if (YES == fullScreen)
	{
		// Get out of full screen mode.
		NSView *contentView = [fullScreenWindow contentView];
		[[self mainWindow] setContentView: contentView];

		ShowMenuBar();
		fullScreen = NO;
	}
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
- (IBAction) cancelFullScreen:(id)sender
{
	if (YES == fullScreen)
	{
		[self toggleFullScreen: sender];
	}
}

//------------------------------------------------------------------------------
- (IBAction) toggleFullScreen:(id)sender
{
	if (NO == fullScreen)
	{
		originalWindow = [self mainWindow];
		[NSCursor setHiddenUntilMouseMoves: YES];

		// Get into full screen mode.
		NSRect screenRect;
		screenRect = [[NSScreen mainScreen] frame];

		// Create a new window
		if (nil == fullScreenWindow)
		{
			fullScreenWindow = [[FullScreenWindow alloc] 
				initWithContentRect: screenRect
				styleMask: NSBorderlessWindowMask
				backing: NSBackingStoreBuffered
				defer: NO];

			[fullScreenWindow useOptimizedDrawing: YES];
			[fullScreenWindow setDelegate: self];
		}

		NSView *contentView = [originalWindow contentView];
		[fullScreenWindow setContentView: contentView];

		HideMenuBar();
		fullScreen = YES;

		[fullScreenWindow makeFirstResponder: fullScreenWindow];
		[fullScreenWindow makeKeyAndOrderFront: fullScreenWindow];
		[originalWindow orderOut: self];
	}
	else
	{
		[NSCursor setHiddenUntilMouseMoves: NO];

		// Get out of full screen mode.
		NSView *contentView = [fullScreenWindow contentView];
		NSWindow *window = originalWindow;
		[window setContentView: contentView];

		ShowMenuBar();
		fullScreen = NO;

		[window makeFirstResponder: window];
		[window makeKeyAndOrderFront: window];
		[fullScreenWindow orderOut: self];
	}

	[self redrawCurrent];
}

//------------------------------------------------------------------------------
- (IBAction) toggleOriginalSize:(id)sender
{
	if (NO == fitWindow)
	{
		fitWindow = YES;
	}
	else
	{
		fitWindow = NO;
	}

	[self fitImage];
	[imageView setNeedsDisplay];
}

//------------------------------------------------------------------------------
- (void) setIsAlreadyFullScreen
{
	fullScreen = YES;
}

//------------------------------------------------------------------------------
- (void) calcAndSetMovieFrame
{
	NSRect frame = [[movieView superview] frame];
	if (YES == movieNaturalSize)
	{
		QTMovie *movie = [movieView movie];
		if (nil != movie)
		{
			NSValue *value = [[movie movieAttributes] valueForKey: QTMovieNaturalSizeAttribute];
			if (nil != value)
			{
				NSSize naturalSize = [value sizeValue];
				if ([movieView isControllerVisible])
				{
					naturalSize.height += [movieView controllerBarHeight];
				}

				// Only resize our view if the movie is smaller than our visible frame.
				if (naturalSize.height <= frame.size.height && naturalSize.width <= frame.size.width)
				{
					frame.origin.x = (frame.size.width - naturalSize.width) / 2;
					frame.origin.y = (frame.size.height - naturalSize.height) / 2;
					frame.size = naturalSize;
				}
			}
		}
	}

	[movieView setFrame: frame];
	[movieView setNeedsDisplay: YES];
	[[movieView superview] setNeedsDisplay: YES];
}

//------------------------------------------------------------------------------
- (void) movieSuperViewFrameChanged: (NSNotification *) notification
{
	[self calcAndSetMovieFrame];
}

//------------------------------------------------------------------------------
- (BOOL) displayMovie:(NSString *) path
{
	NSView *movieSuperView = [movieView superview];
	if (YES == [movieSuperView isHidden])
	{
		[movieView pause: nil];
		[movieView setMovie: nil];
		[[imageView enclosingScrollView] setHidden: YES];
		[movieSuperView setHidden: NO];
	}

	[[movieView window] makeFirstResponder: movieView];
	[movieView pause: nil];

	BOOL ret = NO;
	NSError *error = nil;
	QTMovie *movie = [[QTMovie alloc] initWithFile: path  error: &error];
	if (nil != movie)
	{
		[self calcAndSetMovieFrame];
		[movieView setMovie: movie];
		[movieView gotoBeginning: nil];
		ret = YES;

		[self movieDisplayed: movie];
		[movie release];
	}
	else
	{
		[movieView setMovie: nil];
		NSLog(@"Failed loading movie(%@); error: %@", path, error);
	}

	return ret;
}

//------------------------------------------------------------------------------
// Must be a full path & filename (cannot be just the filename).
// Returns YES if the image was displayed, NO if there was a problem.
- (BOOL) displayImage:(NSString*) fullFilename
{
	if (YES == [[imageView enclosingScrollView] isHidden])
	{
		[movieView pause: nil];
		[[movieView superview] setHidden: YES];
		[[imageView enclosingScrollView] setHidden: NO];

		[movieView setFrame: NSMakeRect(0, 0, 0, 0)];
		[self calcAndSetMovieFrame];
	}

	[[imageView window] makeFirstResponder: [imageView enclosingScrollView]];

	NSImage *img = [[NSImage alloc] initWithContentsOfFile: fullFilename];
	if (nil != img)
	{
		[imageView setImage: img];
		[img release];
		[self fitImage];

		// Ask the owning window to redraw - this allows the window to draw
		// the grow bar, in addition to drawing the actual image, too.
		[[[imageView enclosingScrollView] superview] setNeedsDisplay: YES];

		return YES;
	}

	return NO;
}

//------------------------------------------------------------------------------
- (BOOL) displayFile:(ThumbData *) td
{
	BOOL ret = NO;

	// Display the proper type of media
	switch ([td mediaType])
	{
		case MEDIA_TYPE_IMAGE:
			ret = [self displayImage: [td fullPath]];
			break;

		case MEDIA_TYPE_MOVIE:
			ret = [self displayMovie: [td fullPath]];
			break;

		case MEDIA_TYPE_UNKNOWN:
			ret = NO;
			break;
	}

	return ret;
}

//------------------------------------------------------------------------------
- (void) fitImage
{
	NSSize szWindow = [[imageView enclosingScrollView] frame].size;

	if (YES == fitWindow)
	{
		[imageView setFrameSize: szWindow];

		[[imageView enclosingScrollView] setHasHorizontalScroller: NO];
		[[imageView enclosingScrollView] setHasVerticalScroller: NO];
	}
	else
	{
		NSSize szImage = [imageView getImageSize];

		if (szImage.width > szWindow.width || szImage.height > szWindow.width)
		{
			[imageView setFrameSize: szImage];
			[[imageView enclosingScrollView] setHasHorizontalScroller: YES];
			[[imageView enclosingScrollView] setHasVerticalScroller: YES];
		}
		else
		{
			[imageView setFrameSize: szWindow];
			[[imageView enclosingScrollView] setHasHorizontalScroller: NO];
			[[imageView enclosingScrollView] setHasVerticalScroller: NO];
		}
	}
}

//------------------------------------------------------------------------------
- (BOOL) validateMenuItem:(id <NSMenuItem>) menuItem
{
	// Setup the original size menu
	if ([menuItem action] == @selector(toggleOriginalSize:))
	{
		NSString *menuCaption;
		if (YES == fitWindow)
		{
			menuCaption = NSLocalizedString(@"Show Original Size", @"menu.originalSize");
		}
		else
		{
			menuCaption = NSLocalizedString(@"Fit Image to Window", @"menu.fitWindow");
		}

		[menuItem setTitle: menuCaption];
	}
	else
	// Setup the full screen menu
	if ([menuItem action] == @selector(toggleFullScreen:))
	{
		NSString *menuCaption;
		if (YES == fullScreen)
		{
			menuCaption = NSLocalizedString(@"Cancel Full Screen", @"menu.cancelFullScreen");
		}
		else
		{
			menuCaption = NSLocalizedString(@"Full Screen", @"menu.fullScreen");
		}

		[menuItem setTitle: menuCaption];
	}

	[[Controller sharedController] updateSpecialMenus: (NSMenuItem*) menuItem];

	return NO;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
- (void) setThumbViewState:(int)newState
{
	if (newState < TVS_HIDDEN)
	{
		newState = TVS_HIDDEN;
	}
	else
	if (newState > TVS_RIGHT)
	{
		newState = TVS_RIGHT;
	}

	thumbViewState = newState;
	[[[Controller sharedController] preferencesData] setThumbStripState: thumbViewState];

	NSScrollView *imageScrollView = [imageView enclosingScrollView];
	NSScrollView *thumbScrollView = [thumbView enclosingScrollView];
	NSView *movieSuperView = [movieView superview];

	NSRect winRect = [[[imageView window] contentView] frame];

	if (TVS_HIDDEN == thumbViewState)
	{
		[thumbScrollView setHidden: YES];

		// The image view now takes up the entire window
		[imageScrollView setFrame: winRect];
		[imageScrollView setNeedsDisplay: YES];
		[imageScrollView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];

		[movieSuperView setFrame: winRect];
		[movieSuperView setNeedsDisplay: YES];
		[movieSuperView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
	}
	else
	{
		[thumbScrollView setHidden: NO];

		NSRect imageRect = NSMakeRect(0, 0, winRect.size.width, winRect.size.height);
		NSRect thumbRect = NSMakeRect(0, 0, winRect.size.width, winRect.size.height);

		int imageAutoSize = NSViewWidthSizable | NSViewHeightSizable;
		int thumbAutoSize = 0;
		BOOL thumbViewVertical = NO;

		switch (thumbViewState)
		{
			case TVS_TOP:
				imageRect.size.height -= thumbViewMax;
				imageAutoSize |= NSViewMinYMargin;

				thumbRect.origin.y = imageRect.size.height;
				thumbRect.size.height = thumbViewMax;
				thumbAutoSize |= NSViewMinYMargin | NSViewWidthSizable;
				break;

			case TVS_BOTTOM:
				imageRect.size.height -= thumbViewMax;
				imageRect.origin.y = thumbViewMax;
				imageAutoSize |= NSViewMaxYMargin;

				thumbRect.size.height = thumbViewMax;
				thumbAutoSize |= NSViewMaxYMargin | NSViewWidthSizable;
				break;

			case TVS_LEFT:
				imageRect.size.width -= thumbViewMax;
				imageRect.origin.x = thumbViewMax;
				imageAutoSize |= NSViewMaxXMargin;

				thumbRect.size.width = thumbViewMax;
				thumbAutoSize |= NSViewMaxXMargin | NSViewHeightSizable;
				thumbViewVertical = YES;
				break;

			case TVS_RIGHT:
				imageRect.size.width -= thumbViewMax;
				imageAutoSize |= NSViewMinXMargin;

				thumbRect.origin.x = imageRect.size.width;
				thumbRect.size.width = thumbViewMax;
				thumbAutoSize |= NSViewMinXMargin | NSViewHeightSizable;
				thumbViewVertical = YES;
				break;
		}


		[imageScrollView setFrame: imageRect];
		[imageScrollView setNeedsDisplay: YES];
		[imageScrollView setAutoresizingMask: imageAutoSize];

		[movieSuperView setFrame: imageRect];
		[movieSuperView setNeedsDisplay: YES];
		[movieSuperView setAutoresizingMask: imageAutoSize];

		[thumbView setVertical: thumbViewVertical];
		[thumbScrollView setHasHorizontalScroller: !thumbViewVertical];
		[thumbScrollView setHasVerticalScroller: thumbViewVertical];

		[thumbScrollView setFrame: thumbRect];
		[thumbScrollView setNeedsDisplay: YES];
		[thumbScrollView setAutoresizingMask: thumbAutoSize];
	}

	[[imageScrollView superview] setNeedsDisplay: YES];
}

//------------------------------------------------------------------------------
- (void) setImageStrings
	:(NSString *) fullFilename 
	index:(int) index
	totalCount:(int) totalCount
	date:(NSDate*) date
{
	NSString *format = NSLocalizedString(@"%u of %u", @"setImageStrings");
	NSString* item = [NSString stringWithFormat: format, index, totalCount];
	NSMutableString *caption = [NSMutableString stringWithCapacity: 256];

	NSMutableArray *pathComponents = [NSMutableArray arrayWithArray: [fullFilename pathComponents]];
	while (([pathComponents count] - 1) > pathElements)
	{
		[pathComponents removeObjectAtIndex: 0];
	}
	NSString *captionFile = [NSString pathWithComponents: pathComponents];
	[caption appendString: captionFile];

	if (YES == showName)
	{
		if (YES == fullScreen)
		{
			[imageView setImageName: captionFile];
		}
		else
		{
			[imageView setImageName: nil];
		}
	}
	else
	{
		[imageView setImageName: nil];
	}

	if (YES == showIndex)
	{
		if (YES == fullScreen)
		{
			[imageView setImageIndex: item];
		}
		else
		{
			[imageView setImageIndex: nil];
			[caption appendString: @"  ["];
			[caption appendString: item];
			[caption appendString: @"]"];
		}
	}

	[[imageView window] setTitle: caption];

	[imageView setImageDate
		: [date descriptionWithCalendarFormat
			: @"%Y-%m-%d %H:%M:%S" 
			timeZone: nil 
			locale: nil]];
}

@end
